/*************************************************************************
 * Read and decode a standard INI file. 
 *************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "trim.h"
#include "inifile.h"


int init_displaycontents(init_root * root, FILE* out){
	int i,j;
	for ( i = 0 ; i < root->noofsections ; i++){
		root->sections[i].sectionname?fprintf(out, "[%s]\n", root->sections[i].sectionname):printf("[]\n");
		for (j = 0 ; j < root->sections[i].noofparams ; j ++){
			fprintf(out,"%s=%s\n", root->sections[i].params[j].tag, root->sections[i].params[j].value);
		}
	}
}

/*************************************************************************
 * Free the init sturctue 
 *************************************************************************/
void init_unreadfile(init_root* root){
	int i,j;
	for ( i = 0 ; i < root->noofsections ; i++){
		if(root->sections[i].sectionname)
			free(root->sections[i].sectionname);
		for (j = 0 ; j < root->sections[i].noofparams ; j ++){
			free(root->sections[i].params[j].tag);
			free(root->sections[i].params[j].value);
		}
		free(root->sections[i].params);
	}
	free(root->sections);
	free(root);
}

/*************************************************************************
 * Get a value from a tag in the 'root' section 
 *************************************************************************/
char* init_getstring(const init_root* root,const char* tag){
	return init_getstring_withsection(root, tag, 0);
}

/*************************************************************************
 * Get a value from a tag in a section 
 *************************************************************************/
char* init_getstring_withsection(const init_root* root,const char* tag, const char* sectionname){
	int i,j;
	for (i = 0 ; i < root->noofsections ; i++){
		if(strcmp(root->sections[i].sectionname, sectionname)==0 || sectionname==0){
			for ( j = 0 ; j < root->sections[i].noofparams ; j++){
				if(strcmp(root->sections[i].params[j].tag, tag)==0){
					return root->sections[i].params[j].value;
				}	
			}
			break;
		}
	}
	return 0;
}

/*************************************************************************
 * Read and initialize tags/values/sections 
 *************************************************************************/
init_root* init_readfile(const char* filename, INIFILE_TYPEOFFILE type){
	return init_readfileX(filename, type, 0);
}

init_root* init_readfileX(const char* filename, INIFILE_TYPEOFFILE type, init_root* mainsection){
	char line[INIFILE_MAX_ROW_STRING_SIZE];
	int labelsize;
	char *pequals, *pend, separator;
	init_section* current_section;

	if(mainsection==0){
		mainsection = (init_root*)malloc(sizeof(init_root));
		mainsection->sections = (init_section*)malloc(sizeof(init_section));
		current_section = &mainsection->sections[0];
		current_section->sectionname=0;
		current_section->noofparams=0;
		current_section->params=0;
		mainsection->noofsections=1;
	}
	else{
		current_section = &mainsection->sections[mainsection->noofsections-1];
	}
	
	switch(type){
		case INI_FILE:
			separator='=';
			break;
		case CONF_FILE:
			separator=' ';
			break;
	}

	FILE *fp = fopen(filename, "r");
	if(!fp){
		return 0;
	}
	else{
		while(!feof(fp)){
			memset(line, '\0', INIFILE_MAX_ROW_STRING_SIZE);
			fgets(line, INIFILE_MAX_ROW_STRING_SIZE, fp);
			trim(line);
			if(line[0]!='#' || line[0]!=';'){
				if((pequals=strchr(line, separator))!=0){
					current_section->params = (init_param*)realloc(current_section->params, sizeof(init_param)*(current_section->noofparams+1));

					current_section->params[current_section->noofparams].tag=(char*)calloc((pequals-line+1), sizeof(char));
					current_section->params[current_section->noofparams].value=(char*)calloc((strlen(pequals)+1),sizeof(char));
					trim(memcpy(current_section->params[current_section->noofparams].value, pequals+1, strlen(pequals)+1));
					trim(memcpy(current_section->params[current_section->noofparams].tag, line, pequals-line));

					if(strcasecmp(current_section->params[current_section->noofparams].tag, "include")==0){
						char filename[INIFILE_MAX_ROW_STRING_SIZE];
						strlcpy(filename,current_section->params[current_section->noofparams].value, INIFILE_MAX_ROW_STRING_SIZE);
						free(current_section->params[current_section->noofparams].tag);
						free(current_section->params[current_section->noofparams].value);
					 	current_section->params = (init_param*)realloc(current_section->params, sizeof(init_param)*(current_section->noofparams));
						init_readfileX(filename, type, mainsection);
					}
					else{
						current_section->noofparams++;
					}
				}
				else if(type==INI_FILE && (pequals=strchr(line, '['))!=0 && (pend=strchr(line, ']'))!=0){
					if((labelsize=pend-pequals-1)>0){
						mainsection->noofsections++;
						mainsection->sections = (init_section*)realloc(mainsection->sections, sizeof(init_section)*mainsection->noofsections);
						current_section = &mainsection->sections[mainsection->noofsections-1];
						current_section->noofparams = 0;
						current_section->sectionname = (char*)calloc((labelsize+1), sizeof(char));
						memcpy(current_section->sectionname, pequals+1, labelsize);
					}
					else{
						continue;
					}
				}
			}
		}
		fclose(fp);
		return mainsection;
	}
}
